<?php
declare(strict_types=1);

namespace CommonBundle\Service;

use Psr\Cache\InvalidArgumentException;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\DependencyInjection\ContainerInterface;


class VerifyCodeService
{
    const FILE_CACHE_PATH = '/symfony/cache';

    /** @var ContainerInterface */
    protected $container;
    /** @var \Doctrine\ORM\EntityManager|object */
    protected $em;
    /** @var \Doctrine\Common\Persistence\ObjectRepository|\Doctrine\ORM\EntityRepository */
    protected $rep;

    private $defaultLifetime = 5 * 60;
    private $directory;

    function __construct(ContainerInterface $container)
    {
        $this->container = $container;
        $this->em = $container->get('doctrine.orm.entity_manager');

        $this->directory =
            join('/', [
                sys_get_temp_dir(),
                trim(self::FILE_CACHE_PATH, '/'),
                trim($container->getParameter('database_name'), '/'),
                trim('verify_codes', '/'),
            ]);
    }

    /**
     * @param $mobile
     * @return mixed
     * @throws \Psr\Cache\InvalidArgumentException
     */
    public function getCode($mobile) {
        $cache = new FilesystemAdapter($mobile, $this->defaultLifetime, $this->directory);

        $verifyCode = $cache->getItem("code");

        if ($verifyCode->isHit()) {
            return $verifyCode->get();
        }
        return false;
    }

    /**
     * @param $mobile
     * @return mixed
     */
    public function generateCode($mobile)
    {
        try {
            $cache = new FilesystemAdapter($mobile, $this->defaultLifetime, $this->directory);

            $verifyCode = $cache->getItem("code");
            $freezesTime = $cache->getItem("freezes_time");

            if ($verifyCode->isHit()) {
                // while freezing.
                if ($freezesTime->get() > new \DateTime('now')) {
                    return false;
                }
            }

            // set freezing time
            $time = new \DateTime('now');
            $time->add(\DateInterval::createFromDateString('1 minute'));
            $freezesTime->set($time);
            $cache->save($freezesTime);

            // generate code
            $code = sprintf("%04d", random_int(0, 9999));
            $verifyCode->set($code);
            $cache->save($verifyCode);

            return $code;
        } catch (\Exception $e) {
            return false;
        } catch (InvalidArgumentException $e) {
            return false;
        }
    }
}
